﻿#include "trianglewindow.h"
#include <QDebug>
#include <QImage>

struct VertexData1
{
    QVector3D position;
    QVector3D color;
};

struct VertexData
{
    QVector3D position;
    QVector3D color;
    QVector3D texture;
};

TriangleWindow::TriangleWindow()
    :m_program(0)
    ,m_frame(0)
{
    m_zPosition1 = 0;
    m_zPosition2 = 0;
    m_zPosition3 = 0;
}

TriangleWindow::~TriangleWindow()
{
    for(int i=0;i<10;i++)
    {
        delete &m_VAO[i];
    }
    for(int i=0;i<10;i++)
    {
        delete &m_VBO[i];
    }
    delete m_program;
}

void TriangleWindow::initialize()
{
//    //背景色
//    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    //启用2D纹理映射
    glEnable(GL_TEXTURE_2D);
    //启用混合
    glEnable(GL_BLEND);

    //设置混合参数
//    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    //创建着色器程序
    m_program = new QOpenGLShaderProgram(this);
#ifdef ANDROID
    //编译代码-添加顶点着色器
    m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vshader.vsh");
    //编译代码-添加片段着色器
    m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fshader.fsh");
#else
    //编译代码-添加顶点着色器
    m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/deskvshader.vert");
    //编译代码-添加片段着色器
    m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/deskfshader.frag");
#endif


    //链接着色器
    m_program->link();

    //得到顶点属性名在着色器参数列表中的位置-0
    m_posAttr = m_program->attributeLocation("posAttr");
    //得到颜色属性名在着色器参数列表中的位置-1
    m_colAttr = m_program->attributeLocation("colAttr");
    m_hasTexture = m_program->attributeLocation("hasTexture");
    //得到矩阵规格名在着色器参数列表中的位置-0
    m_projection = m_program->uniformLocation("projection");
    m_view = m_program->uniformLocation("view");
    m_model = m_program->uniformLocation("model");
    //环境光属性
    m_ambientColAttr = m_program->uniformLocation("ambientColAttr");
    //点光源属性
    m_lightColAttr = m_program->uniformLocation("lightColAttr");
    m_lightPosAttr = m_program->uniformLocation("lightPosAttr");
    m_aNormal = m_program->uniformLocation("aNormal");
    m_lightDirection = m_program->uniformLocation("uLightDirection");
    m_lightSpecular = m_program->uniformLocation("uLightSpecular");
    //视点属性
    m_viewPosAttr = m_program->uniformLocation("viewPosAttr");

    //得到纹理属性名在着色器参数列表中的位置-2
    m_texcoordLocation = m_program->attributeLocation("a_texcoord");

    //VAO数据，顶点与颜色
    QVector3D vcs[] = {
        //正面
        QVector3D(-0.5f, 0.0f, 0.5f),
        QVector3D(0.5f, 0.0f, 0.5f),
        QVector3D(0.5f, 1.0f, 0.5f),
        QVector3D(-0.5f, 1.0f, 0.5f),

        QVector3D(0.5f, 0.0f, -0.5f),
        QVector3D(0.5f, 1.0f, -0.5f),
        QVector3D(-0.5f, 1.0f, -0.5f),
        QVector3D(-0.5f, 0.0f, -0.5f),
    };

    VertexData textCoodBg[] = {
        {QVector3D(-0.5f, -0.5f, 0.0f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 0.0f)},     //0
        {QVector3D(-0.5f, 0.5f, 0.0f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 1.0f)},      //1
        {QVector3D(0.5f, -0.5f, 0.0f),  QVector3D(1.0f, 1.0f, 1.0f), QVector2D(1.0f, 0.0f)},      //2


        {QVector3D(-0.5f, 0.5f, 0.0f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 1.0f)},      //1
        {QVector3D(0.5f, -0.5f, 0.0f),  QVector3D(1.0f, 1.0f, 1.0f), QVector2D(1.0f, 0.0f)},      //2
        {QVector3D(0.5f, 0.5f, 0.0f),QVector3D(1.0f, 1.0f, 1.0f), QVector2D(1.0f, 1.0f)},     //3
    };

    //草地
    VertexData textCoodClass[] = {
        {QVector3D(-0.5f, 0.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 0.0f)},     //0
        {QVector3D(-0.5f, 0.0f, -0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 10.0f)},      //1
        {QVector3D(0.5f, 0.0f, 0.5f),  QVector3D(1.0f, 1.0f, 1.0f), QVector2D(10.0f, 0.0f)},      //2


        {QVector3D(-0.5f, 0.0f, -0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 10.0f)},      //1
        {QVector3D(0.5f, 0.0f, 0.5f),  QVector3D(1.0f, 1.0f, 1.0f), QVector2D(10.0f, 0.0f)},      //2
        {QVector3D(0.5f, 0.0f, -0.5f),QVector3D(1.0f, 1.0f, 1.0f), QVector2D(10.0f, 10.0f)},     //3
    };

    //道路
    VertexData textCoodRoad[] = {
        {QVector3D(-1.0f, 0.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 0.0f)},     //0
        {QVector3D(-1.0f, 0.0f, -0.50f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 4.0f)},      //1
        {QVector3D(1.0f, 0.0f, 0.5f),  QVector3D(1.0f, 1.0f, 1.0f), QVector2D(2.0f, 0.0f)},      //2


        {QVector3D(-1.0f, 0.0f, -0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 4.0f)},      //1
        {QVector3D(1.0f, 0.0f, 0.5f),  QVector3D(1.0f, 1.0f, 1.0f), QVector2D(2.0f, 0.0f)},      //2
        {QVector3D(1.0f, 0.0f, -0.5f),QVector3D(1.0f, 1.0f, 1.0f), QVector2D(2.0f, 4.0f)},     //3
    };

    //墙壁
    VertexData textCoodWall[] = {
        {QVector3D(0.0f, 0.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 0.0f)},     //0
        {QVector3D(0.0f, 1.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 4.0f)},      //1
        {QVector3D(0.0f, 0.0f, -0.5f),  QVector3D(1.0f, 1.0f, 1.0f), QVector2D(4.0f, 0.0f)},      //2

        {QVector3D(0.0f, 1.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 4.0f)},      //1
        {QVector3D(0.0f, 0.0f, -0.5f),  QVector3D(1.0f, 1.0f, 1.0f), QVector2D(4.0f, 0.0f)},      //2
        {QVector3D(0.0f, 1.0f, -0.5f),QVector3D(1.0f, 1.0f, 1.0f), QVector2D(4.0f, 4.0f)},     //3
    };

    //网格
    VertexData gridHelper[40];
    QVector3D lineColor(1.0f, 1.0f, 1.0f);
    QVector2D lineTextCood(0.0f, 0.0f);
    int index = 0;
    for(int x=-5; x<=5; x++)
    {
        QVector3D point1(float(x), 0.0f, 5.f);
        QVector3D point2(float(x), 0.0f, -5.f);

        VertexData v1 = {point1, lineColor, lineTextCood};
        VertexData v2 = {point2, lineColor, lineTextCood};
        gridHelper[index] = v1;
        gridHelper[index+1] = v2;
        index += 2;
    }

    for(int z=-5; z<=5; z++)
    {
        QVector3D point1(-5.0f, 0.0f, float(z));
        QVector3D point2(5.0f, 0.0f, float(z));

        VertexData v1 = {point1, lineColor, lineTextCood};
        VertexData v2 = {point2, lineColor, lineTextCood};
        gridHelper[index] = v1;
        gridHelper[index+1] = v2;
        index += 2;
    }

    //三角形条带
    int n = 40;
    m_triCount = 2*(n+1);
    float angleBegin = -0;
    float angleEnd = 360;
    float angleSpan = (angleEnd-angleBegin)/n;
    float radius = 0.6f;
    VertexData *triangleStrip = new VertexData[m_triCount];
    int count = 0;
    QVector3D triColor(1.0f, 1.0f, 1.0f);
    QVector2D triTextCood(0.0f, 0.0f);

    for(float angle = angleBegin; angle<=angleEnd; angle += angleSpan)
    {
        double radian = qDegreesToRadians(angle);

        //外圈点
        VertexData point1 = {QVector3D((float)(-radius*sin(radian)), (float)(radius*cos(radian)), 0.0f), triColor, triTextCood};
        *(triangleStrip+count) = point1;
        count++;

        //内圈点
        VertexData point2 = {QVector3D(-(float)(sin(radian)), (float)(cos(radian)), 0.0f), triColor, triTextCood};
        *(triangleStrip+count) = point2;
        count++;
    }

    //圆形
    int nCircle = 40;
    m_cirCount = nCircle+2;
    float angleSpanCircle = 360.0f/nCircle;
    VertexData* circleTextcood = new VertexData[m_cirCount];
    int countCir = 0;
    QVector3D circleColor(1.0f, 1.0f, 1.0f);
    QVector2D cirTextCood(0.0f, 0.0f);

    VertexData point1 = {QVector3D(0.0f, 0.0f, 0.0f), circleColor, cirTextCood};
    *(circleTextcood+countCir) = point1;
    countCir++;

    for(float angle=0; ceil(angle)<=360; angle+=angleSpanCircle)
    {
        double radian = qDegreesToRadians(angle);
        VertexData point1 = {QVector3D((float)(-sin(radian)), (float)(cos(radian)), 0.0f), circleColor, cirTextCood};
        *(circleTextcood+countCir) = point1;
        countCir++;
    }

    //球形
    float angleSpanBall = 10;
    float r = 0.2f;
    int ballCount = 0;
    m_ballCount = 18*37*6;
    VertexData* ballTextcood = new VertexData[m_ballCount];
    for(int vAngle = -90; vAngle<90; vAngle += angleSpanBall)
    {
        for(int hAngle=0; hAngle<=360; hAngle += angleSpanBall)
        {
            float x0 = (float)(r*sizeof(float) * cos(qDegreesToRadians((double)vAngle)) * cos(qDegreesToRadians((double)hAngle)));
            float y0 = (float)(r*sizeof(float) * cos(qDegreesToRadians((double)vAngle)) * sin(qDegreesToRadians((double)hAngle)));
            float z0 = (float)(r*sizeof(float) * sin(qDegreesToRadians((double)vAngle)));

            float x1 = (float)(r*sizeof(float) * cos(qDegreesToRadians((double)vAngle)) * cos(qDegreesToRadians((double)hAngle+angleSpanBall)));
            float y1 = (float)(r*sizeof(float) * cos(qDegreesToRadians((double)vAngle)) * sin(qDegreesToRadians((double)hAngle+angleSpanBall)));
            float z1 = (float)(r*sizeof(float) * sin(qDegreesToRadians((double)vAngle)));

            float x2 = (float)(r*sizeof(float) * cos(qDegreesToRadians((double)vAngle+angleSpanBall)) * cos(qDegreesToRadians((double)hAngle+angleSpanBall)));
            float y2 = (float)(r*sizeof(float) * cos(qDegreesToRadians((double)vAngle+angleSpanBall)) * sin(qDegreesToRadians((double)hAngle+angleSpanBall)));
            float z2 = (float)(r*sizeof(float) * sin(qDegreesToRadians((double)vAngle+angleSpanBall)));

            float x3 = (float)(r*sizeof(float) * cos(qDegreesToRadians((double)vAngle+angleSpanBall)) * cos(qDegreesToRadians((double)hAngle)));
            float y3 = (float)(r*sizeof(float) * cos(qDegreesToRadians((double)vAngle+angleSpanBall)) * sin(qDegreesToRadians((double)hAngle)));
            float z3 = (float)(r*sizeof(float) * sin(qDegreesToRadians((double)vAngle+angleSpanBall)));

            QVector3D point0(x0, y0, z0);
            QVector3D point1(x1, y1, z1);
            QVector3D point2(x2, y2, z2);
            QVector3D point3(x3, y3, z3);

            VertexData v0 = { point0, circleColor, cirTextCood};
            VertexData v1 = { point1, circleColor, cirTextCood};
            VertexData v2 = { point2, circleColor, cirTextCood};
            VertexData v3 = { point3, circleColor, cirTextCood};

            *(ballTextcood + ballCount) = v0;
            ballCount++;
            *(ballTextcood + ballCount) = v1;
            ballCount++;
            *(ballTextcood + ballCount) = v3;
            ballCount++;

            *(ballTextcood + ballCount) = v1;
            ballCount++;
            *(ballTextcood + ballCount) = v2;
            ballCount++;
            *(ballTextcood + ballCount) = v3;
            ballCount++;
        }
    }


    VertexData vc[] = {
        //正面
        {QVector3D(-0.5f, 0.0f, 0.5f), QVector3D(1.0f, 0.0f, 0.0f), QVector2D(0.0f, 0.0f)},     //1
        {QVector3D(-0.5f, 1.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 1.0f)},     //4
        {QVector3D(0.5f, 0.0f, 0.5f),  QVector3D(0.0f, 1.0f, 0.0f), QVector2D(1.0f, 0.0f)},      //2

        {QVector3D(-0.5f, 1.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 1.0f)},     //4
        {QVector3D(0.5f, 0.0f, 0.5f),  QVector3D(0.0f, 1.0f, 0.0f), QVector2D(1.0f, 0.0f)},      //2
        {QVector3D(0.5f, 1.0f, 0.5f),  QVector3D(0.0f, 0.0f, 1.0f), QVector2D(1.0f, 1.0f)},      //3


        //右面
        {QVector3D(0.5f, 0.0f, 0.5f),  QVector3D(0.0f, 1.0f, 0.0f), QVector2D(0.0f, 0.0f)},     //2
        {QVector3D(0.5f, 1.0f, 0.5f),  QVector3D(0.0f, 0.0f, 1.0f), QVector2D(0.0f, 1.0f)},     //3
        {QVector3D(0.5f, 0.0f, -0.5f), QVector3D(1.0f, 1.0f, 0.0f), QVector2D(1.0f, 0.0f)},     //5        

        {QVector3D(0.5f, 1.0f, 0.5f),  QVector3D(0.0f, 0.0f, 1.0f), QVector2D(0.0f, 1.0f)},     //3
        {QVector3D(0.5f, 0.0f, -0.5f), QVector3D(1.0f, 1.0f, 0.0f), QVector2D(1.0f, 0.0f)},     //5
        {QVector3D(0.5f, 1.0f, -0.5f), QVector3D(0.0f, 1.0f, 1.0f), QVector2D(1.0f, 1.0f)},     //6

        //左面
        {QVector3D(-0.5f, 0.0f, -0.5f),QVector3D(1.0f, 0.0f, 1.0f), QVector2D(0.0f, 0.0f)},     //8        
        {QVector3D(-0.5f, 1.0f, -0.5f),QVector3D(1.0f, 0.6f, 0.0f), QVector2D(0.0f, 1.0f)},     //7
        {QVector3D(-0.5f, 0.0f, 0.5f), QVector3D(1.0f, 0.0f, 0.0f), QVector2D(1.0f, 0.0f)},     //1

        {QVector3D(-0.5f, 1.0f, -0.5f),QVector3D(1.0f, 0.6f, 0.0f), QVector2D(0.0f, 1.0f)},     //7
        {QVector3D(-0.5f, 0.0f, 0.5f), QVector3D(1.0f, 0.0f, 0.0f), QVector2D(1.0f, 0.0f)},     //1
        {QVector3D(-0.5f, 1.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f), QVector2D(1.0f, 1.0f)},     //4


        //背面
        {QVector3D(0.5f, 0.0f, -0.5f),   QVector3D(1.0f, 1.0f, 0.0f), QVector2D(0.0f, 0.0f)},   //5
        {QVector3D(0.5f, 1.0f, -0.5f),   QVector3D(0.0f, 1.0f, 1.0f), QVector2D(0.0f, 1.0f)},   //6
        {QVector3D(-0.5f, 0.0f, -0.5f),  QVector3D(1.0f, 0.0f, 1.0f), QVector2D(1.0f, 0.0f)},   //8

        {QVector3D(0.5f, 1.0f, -0.5f),   QVector3D(0.0f, 1.0f, 1.0f), QVector2D(0.0f, 1.0f)},   //6
        {QVector3D(-0.5f, 0.0f, -0.5f),  QVector3D(1.0f, 0.0f, 1.0f), QVector2D(1.0f, 0.0f)},   //8
        {QVector3D(-0.5f, 1.0f, -0.5f),  QVector3D(1.0f, 0.6f, 0.0f), QVector2D(1.0f, 1.0f)},   //7


        //顶面
        {QVector3D(-0.5f, 1.0f, 0.5f),   QVector3D(1.0f, 1.0f, 1.0f), QVector2D(0.0f, 0.0f)},   //4
        {QVector3D(-0.5f, 1.0f, -0.5f),  QVector3D(1.0f, 0.6f, 0.0f), QVector2D(0.0f, 1.0f)},   //7
        {QVector3D(0.5f, 1.0f, 0.5f),    QVector3D(0.0f, 0.0f, 1.0f), QVector2D(1.0f, 0.0f)},   //3

        {QVector3D(-0.5f, 1.0f, -0.5f),  QVector3D(1.0f, 0.6f, 0.0f), QVector2D(0.0f, 1.0f)},   //7
        {QVector3D(0.5f, 1.0f, 0.5f),    QVector3D(0.0f, 0.0f, 1.0f), QVector2D(1.0f, 0.0f)},   //3
        {QVector3D(0.5f, 1.0f, -0.5f),   QVector3D(0.0f, 1.0f, 1.0f), QVector2D(1.0f, 1.0f)},   //6


        //底面        
        {QVector3D(-0.5f, 0.0f, -0.5f),  QVector3D(1.0f, 0.0f, 1.0f), QVector2D(0.0f, 0.0f)},   //8
        {QVector3D(-0.5f, 0.0f, 0.5f),   QVector3D(1.0f, 0.0f, 0.0f), QVector2D(0.0f, 1.0f)},   //1
        {QVector3D(0.5f, 0.0f, -0.5f),   QVector3D(1.0f, 1.0f, 0.0f), QVector2D(1.0f, 0.0f)},   //5

        {QVector3D(-0.5f, 0.0f, 0.5f),   QVector3D(1.0f, 0.0f, 0.0f), QVector2D(0.0f, 1.0f)},   //1
        {QVector3D(0.5f, 0.0f, -0.5f),   QVector3D(1.0f, 1.0f, 0.0f), QVector2D(1.0f, 0.0f)},   //5
        {QVector3D(0.5f, 0.0f, 0.5f),    QVector3D(0.0f, 1.0f, 0.0f), QVector2D(1.0f, 1.0f)},   //2

    };

    //索引
    GLuint indices[] = { // 起始于0!
        0, 1, 2, 3,// face 1
        1, 4, 5, 2,  // face 2
        0, 7, 6, 3,  // face 3
        4, 5, 6, 7,  // face 4
        2, 5, 6, 3,  // face 5
        1, 4, 7, 0,  // face 6
    };

    //1 使用glGenBuffers函数生成一个缓冲ID    
    glGenVertexArrays(10, m_VAO);
    glGenBuffers(10, m_VBO);
//    glGenBuffers(2, m_EBO);
    //2 绑定vao
    glBindVertexArray(m_VAO[0]);
    //3 使用glBindBuffer函数把新创建的缓冲绑定到GL_ARRAY_BUFFER缓冲类型上
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO[0]); //（绑定和解绑的顺序很重要，勿更改）
//    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO[0]);
    //4 把用户定的义数据复制到当前绑定缓冲的函数
    glBufferData(GL_ARRAY_BUFFER, sizeof(vc), vc, GL_STATIC_DRAW);
//    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(m_posAttr);
    glEnableVertexAttribArray(m_colAttr);
    glEnableVertexAttribArray(m_texcoordLocation);

    //5 链接顶点属性
    //indx: 属性名
    //size: 顶点大小
    //type: 数据类型
    //normalized：数据被标准化
    //stride: 步长
    //ptr: 数据在缓冲中起始位置的偏移量
    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);    //(GLvoid*)0
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*1));
    glVertexAttribPointer(m_texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*2));

    //草地
    glBindVertexArray(m_VAO[1]);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(textCoodClass), textCoodClass, GL_STATIC_DRAW);

    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*1));
    glVertexAttribPointer(m_texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*2));

    //道路
    glBindVertexArray(m_VAO[2]);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO[2]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(textCoodRoad), textCoodRoad, GL_STATIC_DRAW);

    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*1));
    glVertexAttribPointer(m_texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*2));

    //墙壁
    glBindVertexArray(m_VAO[3]);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO[3]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(textCoodWall), textCoodWall, GL_STATIC_DRAW);

    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*1));
    glVertexAttribPointer(m_texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*2));

    //网格
    glBindVertexArray(m_VAO[4]);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO[4]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(gridHelper), gridHelper, GL_STATIC_DRAW);

    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*1));
    glVertexAttribPointer(m_texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*2));

    //三角形条带
    glBindVertexArray(m_VAO[5]);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO[5]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData)*m_triCount, triangleStrip, GL_STATIC_DRAW);

    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*1));
    glVertexAttribPointer(m_texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*2));

    //圆形
    glBindVertexArray(m_VAO[6]);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO[6]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData)*m_cirCount, circleTextcood, GL_STATIC_DRAW);

    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*1));
    glVertexAttribPointer(m_texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*2));

    //球
    glBindVertexArray(m_VAO[7]);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO[7]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData)*m_ballCount, ballTextcood, GL_STATIC_DRAW);

    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*1));
    glVertexAttribPointer(m_texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)(sizeof(QVector3D)*2));

    //6 解绑缓存着色器（绑定和解绑的顺序很重要，勿更改）
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    //7 解绑VAO
    glBindVertexArray(0);

    for(int i=0; i<6; i++)
    {
        //使用图片的垂直镜像来创建纹理
        QString path = QString(":/img/img/cube%1.png").arg(QString::number(i+1));
        QOpenGLTexture *_texture = new QOpenGLTexture(QImage(path).mirrored());
        //设置纹理过滤器的滤波方式
        //当图片缩小的比原始纹理小的时候 滤波方式为 mip层之间使用线性插值和使用线性过滤
        _texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
        //当图片放大的比原始纹理大的时候 滤波方式为 mip基层上使用线性过滤
        _texture->setMagnificationFilter(QOpenGLTexture::Linear);

        m_vTexture.append(_texture);
    }

    //使用纹理单元
    m_program->setUniformValue("texture", 0);

    const GLubyte * name = glGetString(GL_VENDOR);
    const GLubyte * biaoshifu = glGetString(GL_RENDERER);
    const GLubyte * OpenGLVersion = glGetString(GL_VERSION);
//    const GLubyte * gluVersion = gluGetString(GLU_VERSION);

    qDebug()<<*name<<*biaoshifu<<*OpenGLVersion;

}

void TriangleWindow::render()
{
    //背景色
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    //重置视口
    glViewport(0, 0, getViewportSize().width(), getViewportSize().height());

    //清除颜色缓冲区
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);

    //绑定着色器程序到活动的上下文
    m_program->bind();    

    //4x4 矩阵
    QMatrix4x4 projection, view, model;
    float ratio = (float)(getViewportSize().width() / getViewportSize().height());
    ratio = 4.0f / 3.0f;
    //正交投影
//    projection.ortho(-ratio, ratio, -1.0f, 1.0f, 0.1f, 100.0f);
    //乘以一个矩阵，为了建立透视投影矩阵
    projection.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
    //乘以这个矩阵，通过向量转换坐标
    GLfloat camX = sin((GLfloat)m_frame/100) * 3.0f;
    GLfloat camZ = cos((GLfloat)m_frame/100) * 3.0f;
    QVector3D camera = QVector3D(0.0f, 3.0f, 5.0f);
    view.lookAt(camera, QVector3D(0.0f, 0.0f, 0.0f), QVector3D(0.0f, 1.0f, 0.0f));
    //乘以这个矩阵，通过向量上的角度旋转坐标
    model.translate(0.0f, 0.0f, 0.0f);
    model.rotate(m_frame, 0, 1, 0);

    //设置矩阵数据
    m_program->setUniformValue(m_projection, projection);
    m_program->setUniformValue(m_view, view);
    m_program->setUniformValue(m_model, model);
    m_program->setUniformValue(m_hasTexture, 1);

    //环境光
    QVector3D ambient(0.5f, 0.5f, 0.5f);
    m_program->setUniformValue(m_ambientColAttr, ambient);

    //点光源-漫反射
    QVector3D pointLightCol(1.0f, 1.0f, 1.0f);
    m_program->setUniformValue(m_lightColAttr, pointLightCol);

    QVector3D pointLightPos(1.0f, m_xPositionCamera, 0.0f);
    m_program->setUniformValue(m_lightPosAttr, pointLightPos);

    QVector3D lightSpecular(1.0f, 1.0f, 1.0f);
    m_program->setUniformValue(m_lightSpecular, lightSpecular);

    QVector3D lightDirection(1.0f, m_xPositionCamera, 0.0f);
    m_program->setUniformValue(m_lightDirection, lightDirection);

    //法线=强度
    QVector3D objNormal(0.0f, 1.0f, 0.0f);
    m_program->setUniformValue(m_aNormal, objNormal);

    //视点为摄像机位置
    m_program->setUniformValue(m_viewPosAttr, camera);

    //1 绑定vaoshi
    glBindVertexArray(m_VAO[0]);

    //2 开启顶点属性
    glEnableVertexAttribArray(m_posAttr);
    //颜色值
    glEnableVertexAttribArray(m_colAttr);
    //纹理
    glEnableVertexAttribArray(m_texcoordLocation);

    QMatrix4x4 modelCube1;
    modelCube1.translate(0.0f, 0.0f, 0.0f);
    modelCube1.rotate(m_frame, 0, 1, 0);
    modelCube1.scale(1.0f);
    m_program->setUniformValue(m_model, modelCube1);
    m_program->setUniformValue(m_hasTexture, 0);

    //纹理绑定
    for(int i=0; i<6; i++)
    {
        m_vTexture.at(i)->bind();
        //3 绘制四边形
        //24个索引值
        glDrawArrays(GL_TRIANGLES, i*6, 6);

        m_vTexture.at(i)->release();
    }

    //网格
    glBindVertexArray(m_VAO[4]);
    glEnableVertexAttribArray(m_posAttr);
    glEnableVertexAttribArray(m_colAttr);

    QMatrix4x4 modelHelper;
    modelHelper.translate(0.0f, 0.0f, 0.0f);
    m_program->setUniformValue(m_model, modelHelper);
//    m_program->setUniformValue(m_hasTexture, 0);

    m_vTexture.at(0)->bind();
    glDrawArrays(GL_LINES, 0, 40);
    m_vTexture.at(0)->release();

//    //三角形条带
//    glBindVertexArray(m_VAO[5]);
//    glEnableVertexAttribArray(m_posAttr);
//    glEnableVertexAttribArray(m_colAttr);

//    QMatrix4x4 modelTri;
//    modelTri.translate(2.0f, 0.0f, 1.0f);
//    m_program->setUniformValue(m_model, modelTri);
//    m_program->setUniformValue(m_hasTexture, 0);

//    m_vTexture.at(0)->bind();
//    glDrawArrays(GL_TRIANGLE_STRIP, 0, m_triCount);
//    m_vTexture.at(0)->release();

    //圆形
    glBindVertexArray(m_VAO[6]);
    glEnableVertexAttribArray(m_posAttr);
    glEnableVertexAttribArray(m_colAttr);

    QMatrix4x4 modelCir;
    modelCir.translate(pointLightPos);
    modelCir.scale(0.1);
    m_program->setUniformValue(m_model, modelCir);


    m_vTexture.at(0)->bind();
    glDrawArrays(GL_TRIANGLE_FAN, 0, m_cirCount);
    m_vTexture.at(0)->release();

    //球
    glBindVertexArray(m_VAO[7]);
    glEnableVertexAttribArray(m_posAttr);
    glEnableVertexAttribArray(m_colAttr);

    QMatrix4x4 modelBall;
    modelBall.translate(2.0f, 0.0f, 0.0f);
    modelBall.rotate(m_frame, 0, 1, 0);
    m_program->setUniformValue(m_model, modelBall);
    m_program->setUniformValue(m_hasTexture, 0);

    m_vTexture.at(0)->bind();
    glDrawArrays(GL_TRIANGLES, 0, m_ballCount);
    m_vTexture.at(0)->release();

    //4 停用对应的顶点属性数组
    glDisableVertexAttribArray(m_texcoordLocation);
    glDisableVertexAttribArray(m_colAttr);
    glDisableVertexAttribArray(m_posAttr);

    //5 解绑VAO
    glBindVertexArray(0);

    //释放程序
    m_program->release();

    //计算是否碰撞了立方体

    QVector3D cube1(-2.0f, 2.0f, m_zPosition1);
    QVector3D cube2(0.0f, 2.0f, m_zPosition2);
    QVector3D cube3(2.0f, 2.0f, m_zPosition3);
    float len1 = camera.distanceToPoint(cube1);
    float len2 = camera.distanceToPoint(cube2);
    float len3 = camera.distanceToPoint(cube3);

    if(len1<=1.4 || len2<=1.4 || len3<=1.4){
        emit pengzhuang();
    }


//    m_frame++;

}
